/*! \file MceIrDrv.h Holds the actual MceIr driver code. */
#ifndef __MCE_IR_DRV_H_INCLUDED__
#define __MCE_IR_DRV_H_INCLUDED__

#include <string>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include "IMceIrDrv.h"
#include "MceTypes.h"
#include "ILogger.h"
#include "Publisher.h"
#include "IrDecoderManager.h"

/*! This class communicates with the MceIr Driver on Vista and Win7. */
class MceIrDrv : public IMceIrDrv {
private:

	std::string m_DevicePath;	
	HANDLE m_DeviceFile;
	HANDLE m_Thread;
	HANDLE m_Event;

	enum EventEnum { QuitEvent, ChangeModeEvent };
	EventEnum m_EventType;	
	
	PtrSize m_ReceiverMask;
	PtrSize m_PortToUse;
	PtrSize m_LearnPort;
	PtrSize m_ReceivePort;
	PtrSize m_TransmitMask;
	
	bool m_Terminated;
	ILoggerPtr m_Logger;
	IrDecoderManagerPtr m_Decoder;

	DWORD threadProc ();
	static  DWORD WINAPI _threadProc ( void * data );
	
	bool DeviceIo( DWORD IoCtlCode, void * inBuffer, DWORD inBufferSize, void * outBuffer, DWORD outBufferSize, DWORD & bytesReturned, DWORD timeout );
	bool DeviceIo( DWORD IoCtlCode, void * inBuffer, DWORD inBufferSize, void * outBuffer, DWORD outBufferSize, DWORD & bytesReturned, DWORD timeout, bool dontInterrupt, bool & interupted );
	bool read ( void * receiveParams, int receiveParamsSize );
	void Process(DWORD connectCount);
	bool LoadCapabilities ();
	bool startReceive(PtrSize portToUse, PtrSize timeout);
	bool stopReceive();
	void sendToDecoder(DWORD *pData, DWORD len);

public:
	MceIrDrv( ILoggerPtr logger, IrDecoderManagerPtr irDecoderManger, const char * devicePath);
	~MceIrDrv();
	void init();
	bool isConnected();
	bool transmit ( PtrSize * command, size_t commandLen, PtrSize transmitMask, PtrSize period );
	bool getTransmitMask ( PtrSize & transmitMask );
	std::string getPath ( );
};

#endif

